<!--
 * @Author: Bobby
 * @Date: 2021-12-30 10:01:42
 * @LastEditTime: 2022-02-15 17:58:57
 * @LastEditors: Bobby
 * @Description:
 * @FilePath: \wms-v2\src\ve\elements\other\uiCascader\uiCascader.vue
 * CIMC-V2
-->
<template>
  <UiFormItem :class="{ hidden: info.extension.hidden.value || conditionProperty.hidden }" :info="info">
    <div :ref="info._id" v-ui-ref="vSetRef" class="w-full">
      <el-cascader
        v-model="formDataModel"
        class="w-full"
        clearable
        collapse-tags
        :disabled="info.extension.disabled.value || conditionProperty.disabled"
        :filterable="info.extension.filterable.value"
        :options="optionList"
        :props="{
          label: info.extension.labelField.value,
          value: info.extension.valueField.value,
          children: info.extension.childrenField.value,
          multiple: info.extension.multiple.value,
          checkStrictly: info.extension.checkStrictly.value,
          expandTrigger: info.extension.expandTrigger.value,
        }"
        :show-all-levels="!info.extension.lastLevel.value"
        size="mini"
        @blur="funblur"
        @change="handleChange"
      />
    </div>
  </UiFormItem>
  <!-- :show-all-levels="info.extension.showAllLevels.value" -->
</template>
<script>
  import { getCascaderShow } from '@ve/utils/utils'
  import request from '@/utils/request'
  import { GFCD } from '@/utils/utils'
  import isEmpty from 'lodash/isEmpty'
  import merge from 'lodash/merge'
  import trim from 'lodash/trim'
  import isArray from 'lodash/isArray'
  import { processingConstant } from '@ve/utils/utils'
  import { defineComponent } from 'vue'
  import cloneDeep from 'lodash/cloneDeep'
  import { UiMixin, ElementsFormMixin, RefsInjectMixin, ConditionMixin } from '@ve/mixin'
  export default defineComponent({
    name: 'UiCascader',
    components: {},
    mixins: [UiMixin, ElementsFormMixin, RefsInjectMixin, ConditionMixin],
    data() {
      return {
        optionList: [],
        lastNewval: {},
      }
    },
    created() {
      this.optionList = this.info.extension.optionConfig.value
    },
    mounted() {
      // 判断是否有配置获取选项
      if (this.hasPreview && this.info.extension.api.value) {
        if (this.info.extension.dontRequest && this.info.extension.dontRequest.value) return
        this.requestOptionList()
      }
    },
    methods: {
      getCascaderLevel() {
        let promises = this.optionList.map((el) => {
          let key = this.info.extension?.sublevelKey?.value
          let obj = {}
          obj[key] = el[key] || el[this.info.extension.valueField.value]
          let requestDataObj = {}
          isArray(this.info.extension.requestData.value) &&
            this.info.extension.requestData.value.forEach((item) => {
              let itemVal = item.value
              requestDataObj[item.key] = processingConstant(this, itemVal)
            })
          // console.log(merge(requestDataObj, obj, this.info?.data?.formData))
          return request({
            url: GFCD('dams', 'domain') + this.info.extension.sublevelApi.value,
            method: 'post',
            data: {
              data: JSON.stringify(merge(requestDataObj, obj, this.info?.data?.formData)),
              method: this.info.extension.sublevelMethod.value,
            },
          })
        })
        Promise.all(promises).then((posts) => {
          this.optionList.forEach((row, i) => {
            if (this.info.extension.levellLabelField?.value) {
              row[this.info.extension.labelField.value] = row[this.info.extension.levellLabelField.value]
            }
            if (this.info.extension.levelValueField?.value) {
              row[this.info.extension.valueField.value] = row[this.info.extension.levelValueField.value]
            }
            row.children = posts[i].data[this.info.extension.sublevelMethod.value].data
            row.children.forEach((r) => {
              r.leaf = true
              if (!r[this.info.extension.valueField.value]) {
                r[this.info.extension.valueField.value] = r[this.info.extension.sublevelValueField.value]
              }
              if (!r[this.info.extension.labelField.value]) {
                r[this.info.extension.labelField.value] = r[this.info.extension.sublevelLabelField.value]
              }
            })
            if (row.children.length == 0) {
              row.disabled = true
            }
          })
          console.log(this.optionList)
        })
      },
      requestOptionList(cb) {
        let requestDataObj = {}
        isArray(this.info.extension.requestData.value) &&
          this.info.extension.requestData.value.forEach((item) => {
            let itemVal = item.value
            if (/{[^#{]+}/g.test(item.value)) {
              itemVal = this.info.data.formData[trim(item.value.substring(2, item.value.length - 1))]
            }
            requestDataObj[item.key] = processingConstant(this, itemVal)
          })
        let options = {
          api: this.info.extension.api.value,
          method: this.info.extension.method.value,
          getDataKey: this.info.extension.getDataKey.value,
          data: merge(requestDataObj, this.info?.data?.formData),
        }
        if (!trim(options.api)) return
        this.request(options, cb)
      },
      request(options = {}, cb = null) {
        this.loading = true
        let getDataKey = options.getDataKey
        //发起请求
        return request({
          url: GFCD('dams', 'domain') + options.api,
          method: 'post',
          data: {
            data: JSON.stringify(options.data),
            method: options.method,
          },
        }).then((res) => {
          this.loading = false
          //解密
          // console.log(decryptd(res))
          // this.getInfo.data.requestData = isEmpty(getDataKey) ? res.data : res.data[getDataKey]
          if (!this.info.extension.sublevelApi.value && !this.info.extension.sublevelMethod.value) {
            let requestData = isEmpty(getDataKey) ? res.data.data || [] : res.data[getDataKey].data || []
            console.log('requestData', requestData)
            const isCheckeds = requestData
              .filter((el) => el.ISCHECKED === 1)
              .map((v) => v[this.info.extension.sublevelValueField.value])
              .join(',')

            this.optionList = this.setCascaderConstruction(requestData)
            if (this.info.extension?.multipleLast?.value) {
              this.formDataModel = getCascaderShow(
                this.optionList,
                isCheckeds,
                this.info.extension.childrenField.value,
                this.info.extension.sublevelValueField.value,
                this.info.extension.levelKey.value
              )
            }
          } else {
            this.optionList = isEmpty(getDataKey) ? res.data.data || [] : res.data[getDataKey].data || []
            if (this.optionList.length > 0 && this.info.extension.sublevelApi.value) {
              console.log('this.optionList===========', cloneDeep(this.optionList))
              this.getCascaderLevel()
            }
          }
          if (this.formDataModel && !this.info.extension.showLastLevel.value && this.info.data.formData.flag == 'Y') {
            let resData = isEmpty(getDataKey) ? res.data.data || [] : res.data[getDataKey].data || []
            console.log('this.optionList===========', resData, this.info.extension.superiorKey.value)
            let levelKey = resData.find((el) => el[this.info.extension.superiorKey.value] == this.formDataModel)[
              this.info.extension.allLevelKey.value
            ]
            this.deleteChildren(this.optionList, levelKey)
          } else if (!this.info.extension.showLastLevel.value && this.info.data.formData.flag == 'Y') {
            let resData = isEmpty(getDataKey) ? res.data.data || [] : res.data[getDataKey].data || []
            let levelKey = resData.find((el) => el[this.info.extension.levelKey.value] == this.formDataModel)[this.info.extension.levelKey.value]
            console.log('this.optionList===========', levelKey)
            if (levelKey === 0) {
              this.optionList = []
            }
          }
          // 回调
          cb && cb(res)
        })
      },
      deleteChildren(_data, level) {
        _data.forEach((r) => {
          if (r[this.info.extension.allLevelKey.value] == level) {
            r.children = []
          }
          if (r.children && r.children.length > 0) {
            this.deleteChildren(r.children, level)
          }
        })
      },
      setCascaderConstruction(list) {
        let result = []
        if (this.info.extension.associationSuperior && this.info.extension.associationSuperior.value) {
          result = this.ArrayToTree(
            list,
            this.info.extension.associationSuperior.value,
            this.info.extension.superiorKey.value,
            this.info.extension.levelKey.value
          )
        } else {
          let leveId = this.info.extension.associationSuperior.value === '0' ? '0' : ''
          result = this.ArrayToTree(list, leveId, this.info.extension.superiorKey.value, this.info.extension.levelKey.value)
        }
        console.log('result', result, list, this.info.extension.superiorKey.value, this.info.extension.levelKey.value)
        return result
      },
      ArrayToTree(arr, first, id, pid) {
        // 判断是否是数组 不是数组就返回 []
        if (!Array.isArray(arr) || !arr.length) return []
        let newArr = []
        arr.forEach((item) => {
          // 判断 当前item.pid 和 传入的pid 是否相等，相等就push 进去
          if (item[pid] == first) {
            newArr.push({
              ...item,
              children: this.ArrayToTree(arr, item[id], id, pid),
            })
          }
        })
        return newArr
      },
      handleChange() {
        // 触发条件判断值改变
        this.setPageModulesState('value', this.formDataModel)
        // 调用 change 事件
        this.onChange()
      },
      funblur() {
        //blur事件触发验证
        // if (JSON.stringify(this.getInfo.extension.extendRule.value || {}) !== '{}') {
        //   this.vuiComponents[this.formId].ref.validateField([this.getInfo.extension.model.value])
        // }
      },
      dataSourceChange(newval) {
        setTimeout(() => {
          // console.log('selsect 绑定值改变了呦····················', newval)
          // console.log('this.lastNewval %%%%%%%%%%%%%%', this.lastNewval)
          // debugger
          // 判断是否有值改变
          let changeFlag = false
          if (trim(this.info.dataSourceBind.getDataKey?.value)) {
            // 如果有获取数据Key 则判断获取的数据是否改变
            const keyList = this.info.dataSourceBind.getDataKey?.value.split(',')
            isArray(keyList) &&
              keyList.forEach((keyItem) => {
                keyItem = trim(keyItem)
                if (newval[keyItem] !== this.lastNewval[keyItem]) {
                  changeFlag = true
                }
              })
          } else {
            Object.keys(newval).map((v) => {
              if (newval[v] !== this.lastNewval[v]) {
                changeFlag = true
              }
            })
          }
          // if (isEmpty(this.lastNewval)) {
          //   changeFlag = true
          // } else {
          //   Object.keys(newval).map((v) => {
          //     if (newval[v] !== this.lastNewval[v]) {
          //       changeFlag = true
          //     }
          //   })
          // }
          if (changeFlag) {
            this.lastNewval = cloneDeep(newval)
          } else {
            // 如果值未改变则不进行后续操作
            return
          }
          // console.log('this.lastNewval 22222222222222222', this.lastNewval)
          let _obj = {}
          Object.keys(this.getInfo.data.formData).map((v) => {
            _obj[v] = ''
          })
          let _mergeData = {}
          // 根据 getDataKey 筛选需要的数据
          // console.log('trim(this.dataSource.getDataKey)', trim(this.dataSource.getDataKey))
          if (!trim(this.info.dataSourceBind.getDataKey?.value)) {
            // 如果没有 getDataKey 则返回全量数据
            _mergeData = newval
          } else {
            const keyList = this.info.dataSourceBind.getDataKey?.value.split(',')
            isArray(keyList) &&
              keyList.forEach((item) => {
                item = trim(item)
                if (newval[item] !== undefined) {
                  // 如果传过来的对象里面没有要取得值 则丢弃
                  _mergeData[item] = newval[item]
                }
              })
          }
          let _data = isEmpty(_mergeData)
            ? _obj
            : {
                ...this.getInfo.data.formData,
                ..._mergeData,
              }
          // console.log('_mergeData ========= ', _mergeData)
          // console.log('_data ========= ', _data)
          this.getInfo.data.formData = _data
          console.log('this.optionList1========')
          // 请求数据
          this.requestOptionList()
        }, 1)
      },
    },
  })
</script>
<style lang="scss" scoped>
  :deep() .el-cascader__search-input {
    margin-left: 7px;
  }
</style>
